export interface oa {
  [propName: string]: any;
}
import { existsSync, statSync, unlinkSync, mkdirSync, readFileSync, appendFileSync, writeFileSync } from "fs";
import { resolve } from "path";
import { uuid } from "@mac-xiang/method";
const sf = [",", "\n", "\r"];
export function mkdir(path: string) {
  let t: any = path.replace(/\\/g, "/");
  const cwd = process.cwd().replace(/\\/g, "/");
  const fullPath: string = t.indexOf(cwd) == 0 ? t : resolve(cwd, t).replace(/\\/g, "/");
  const pa: string[] = fullPath.split("/");
  let dir: string;
  const l = pa.length + 1;
  for (let i = 1; i < l; i++) {
    dir = pa.slice(0, i).join("/");
    if (existsSync(dir)) {
      t = statSync(dir);
      if (!t.isDirectory()) unlinkSync(dir);
    }
    if (!existsSync(dir)) mkdirSync(dir);
  }
}
export class LOG {
  private dir: string;
  private suffix: string;

  constructor (filePath?: string, suffix = ".log") {
    this.dir = this.getPath(filePath);
    this.suffix = suffix;
  }
  getPath(filePath?: string) {
    const r = resolve(__dirname, filePath ? filePath : resolve(process.cwd(), "logs/chats"));
    if (existsSync(r)) {
      if (statSync(r).isFile()) {
        unlinkSync(r);
        mkdirSync(r);
      }
    } else {
      mkdir(r);
    }
    return r;
  }
  getFileName(p: string) {
    let ret = p;
    if (ret.lastIndexOf(this.suffix) < 0 || ret.lastIndexOf(this.suffix) != ret.length - this.suffix.length) {
      ret += this.suffix;
    }
    return resolve(this.dir, ret);
  }
  readLog(file: string): oa[] | undefined {
    const f = this.getFileName(file);
    if (existsSync(f) && statSync(f).isFile()) {
      let buffer = readFileSync(f, "utf8"); // readFileSync的第一个参数是文件名
      while (sf.indexOf(buffer.substr(-1)) >= 0) {
        buffer = buffer.substr(0, buffer.length - 1);
      }
      return JSON.parse(`[${buffer}]`) as oa[];
    }
  }
  write(file: string, data: any, line = -1, insert = true) {
    if (typeof data != "undefined") {
      const f = this.getFileName(file),
        text = JSON.stringify(data);
      if (line < 0 && existsSync(f)) {
        appendFileSync(f, text + ",\n");
      } else {
        let buffer: string[] = [];
        if (existsSync(f)) {
          buffer = (this.readLog(f) as []).map(a => {
            return JSON.stringify(a);
          });
          buffer.splice(line, insert ? 0 : 1, text);
        } else {
          buffer = Array.isArray(data) ? data.map(a => { return JSON.stringify(a); }) : [text];
        }
        writeFileSync(f, buffer.join(",\n") + ",\n");
      }
    }
  }
  get newLog() {
    let ret = "";
    do {
      ret = uuid;
    } while (existsSync(this.getFileName(ret)));
    return ret;
  }
}


interface cacheSign {
  pid: number;
  sign: string;
  path: string[];
}
export interface setCache extends cacheSign {
  value: any;
  push?: any;
}
/** 读取方法method值 【比特位】 如下:
 * @1: 读取后删除; 设置比特位2时无效
 * @2: 读取_tmkTimeData数据时有效,根据传递path的第二个元素查找history子项,返回拥有此参数的父级key
 */
export interface getCache extends cacheSign {
  method: number;
}
export interface delCache extends cacheSign {
  pop?: any;
}
export type ns = number | string;

export interface funGetCache {
  (param: undefined | ns | ns[]): Promise<oa>;
}
export interface funSetCache {
  (node: ns | ns[], data: any): Promise<boolean>;
}
export interface funDelCache {
  (node: ns | ns[]): Promise<boolean>;
}
export interface HistoryS {
  [node: string]: Array<any>;
}
export interface TmkTimeData {
  time?: number;
  // sid: string;
  rooms: string[];
  history?: HistoryS;
  [node: string]: any;
}
export interface Cache {
  _tmkTimeData: { [node: string]: TmkTimeData; };
  [node: string]: any;
}